{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "### 〇，编程环境"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "1,安装Java\n",
    "\n",
    "2,配置Java环境变量\n",
    "\n",
    "3,安装Scala\n",
    "\n",
    "4,配置Scala环境变量\n",
    "\n",
    "参考菜鸟教程： https://www.runoob.com/scala/scala-install.html\n",
    "\n",
    "5，配置jupyter-scala环境\n",
    "\n",
    "下载以下kernel文件，解压缩后根据readme.txt中的指引操作即可\n",
    "\n",
    "https://github.com/rvilla87/Big-Data/raw/master/other/jupyter-Scala_2.11.11_kernel_Windows.zip"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 一，算数运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:35.473485Z",
     "start_time": "2019-08-25T10:19:27.700Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "31"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//四则运算\n",
    "1+(100-20)/4+5*2 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:37.593958Z",
     "start_time": "2019-08-25T10:19:36.698Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//求模运算\n",
    "5%2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:39.066105Z",
     "start_time": "2019-08-25T10:19:38.214Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8.0"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//乘方运算\n",
    "math.pow(2,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:40.039124Z",
     "start_time": "2019-08-25T10:19:39.042Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//绝对值\n",
    "math.abs(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:40.906936Z",
     "start_time": "2019-08-25T10:19:39.876Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1.0"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//三角函数\n",
    "math.cos(math.Pi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:41.771699Z",
     "start_time": "2019-08-25T10:19:40.679Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.605170185988092"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//对数函数\n",
    "math.log(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:42.503026Z",
     "start_time": "2019-08-25T10:19:41.486Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "22026.465794806718"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//指数函数\n",
    "math.exp(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二，输入输出"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输出：println,print,printf\n",
    "\n",
    "输入：scala.io.StdIn\n",
    "\n",
    "读文件：scala.io.Source\n",
    "\n",
    "写文件：java.io.PrintWriter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，输出**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:45.309601Z",
     "start_time": "2019-08-25T10:19:44.324Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n",
      "hello China \n",
      "I'm Jimmy,I'm 17,my weight is 46.50 kg"
     ]
    }
   ],
   "source": [
    "//println换行，print不换行，printf格式化字符串\n",
    "println(\"hello world\")\n",
    "print(\"hello \")\n",
    "print(\"China \\n\")\n",
    "printf(\"I'm %s,I'm %d,my weight is %.2f kg\",\"Jimmy\",17,46.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，输入**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:46.336012Z",
     "start_time": "2019-08-25T10:19:45.695Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input a sentencenull\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "s: String = null\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "//readLine读入行，readInt读入整数\n",
    "//readDouble读入浮点数，readBoolean读入布尔值\n",
    "import scala.io.StdIn\n",
    "val s = StdIn.readLine(\"input a sentence\")\n",
    "println(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3，读文件** "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:48.856216Z",
     "start_time": "2019-08-25T10:19:47.574Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "f = empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "empty iterator"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//读文件\n",
    "import scala.io.Source\n",
    "val f = Source.fromFile(\"data.txt\")\n",
    "f.foreach(print)\n",
    "f.close"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:49.873540Z",
     "start_time": "2019-08-25T10:19:48.188Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "f = empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "empty iterator"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//读文件\n",
    "import scala.io.Source\n",
    "val f=Source.fromFile(\"data.txt\")\n",
    "for(line <- f.getLines)\n",
    "{\n",
    "  println(line)\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:50.571791Z",
     "start_time": "2019-08-25T10:19:48.776Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "f = empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "empty iterator"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//读文件\n",
    "import scala.io.Source\n",
    "val f = Source.fromFile(\"data.txt\")\n",
    "println(f.mkString)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:53.328310Z",
     "start_time": "2019-08-25T10:19:49.423Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "List(1, 2, 3, 4, 5)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "f = empty iterator\n",
       "s = List(1, 2, 3, 4, 5)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(1, 2, 3, 4, 5)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//读文件\n",
    "import scala.io.Source\n",
    "val f = Source.fromFile(\"data.txt\")\n",
    "val s = f.getLines.toList\n",
    "println(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:54.608827Z",
     "start_time": "2019-08-25T10:19:50.097Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12345\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "f = empty iterator\n",
       "s = 12345\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "12345"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//读文件\n",
    "import scala.io.Source\n",
    "val f = Source.fromFile(\"data.txt\")\n",
    "val s = f.getLines.mkString\n",
    "println(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:54.802740Z",
     "start_time": "2019-08-25T10:19:51.228Z"
    }
   },
   "outputs": [],
   "source": [
    "f.close"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**4，写文件**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:56.096261Z",
     "start_time": "2019-08-25T10:19:52.549Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "out = java.io.PrintWriter@43e57f0e\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "java.io.PrintWriter@43e57f0e"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import java.io._\n",
    "val out = new PrintWriter(\"data.txt\")\n",
    "for (i<- 1 to 5) out.println(i)\n",
    "out.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:19:56.902105Z",
     "start_time": "2019-08-25T10:19:52.861Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "writer = java.io.PrintWriter@3863682e\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "java.io.PrintWriter@3863682e"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import java.io._\n",
    "val writer = new PrintWriter(new File(\"text.txt\" ))\n",
    "writer.write(\"hello world\\n\")\n",
    "writer.write(\"hello China\")\n",
    "writer.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "### 三，导入包Package"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "scala有以下一些常见的导入package的方式\n",
    "\n",
    "1,引入包中全部对象 (import scala.io._)\n",
    "\n",
    "2,引入某个对象 (import scala.io.StdIn)\n",
    "\n",
    "3,引入某些对象 (import scala.io.{StdIn,Source})\n",
    "\n",
    "4,引入后重命名 (import scala.io.{Source => Src,StdIn})\n",
    "\n",
    "5,隐藏某些对象 (import scala.io.{Source => _,StdIn})\n",
    "\n",
    "6,隐式引入 (java.lang_,scala._,Predef._默认被引入)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:00.305784Z",
     "start_time": "2019-08-25T10:19:59.462Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n",
      "hello China\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "f = empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "empty iterator"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//不引入，直接用全名使用\n",
    "val f = scala.io.Source.fromFile(\"text.txt\")\n",
    "f.getLines.foreach(println)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:00.975859Z",
     "start_time": "2019-08-25T10:20:00.579Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n",
      "hello China\n",
      "input a sentencenull\n"
     ]
    }
   ],
   "source": [
    "//引入全部\n",
    "import scala.io._\n",
    "println(Source.fromFile(\"text.txt\").mkString)\n",
    "println(StdIn.readLine(\"input a sentence\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:01.953081Z",
     "start_time": "2019-08-25T10:20:01.472Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n",
      "hello China\n",
      "input a sentencenull\n"
     ]
    }
   ],
   "source": [
    "//引入某些类\n",
    "import scala.io.{Source,StdIn,BufferedSource}\n",
    "println(Source.fromFile(\"text.txt\").mkString)\n",
    "println(StdIn.readLine(\"input a sentence\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:02.655345Z",
     "start_time": "2019-08-25T10:20:02.295Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "import scala.io.{Source=>Src, StdIn}\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n",
      "hello China\n"
     ]
    }
   ],
   "source": [
    "//引入后重命名\n",
    "import scala.io.{Source => Src,StdIn}\n",
    "println(Src.fromFile(\"text.txt\").mkString)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:03.350322Z",
     "start_time": "2019-08-25T10:20:03.079Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "import scala.io.{Source=>_, StdIn}\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "//隐藏Source\n",
    "import scala.io.{Source => _,StdIn}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:04.828090Z",
     "start_time": "2019-08-25T10:20:03.829Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "23123"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//隐式导入\n",
    "//java.lang包，scala包以及Predef对象是所有scala程序默认导入的\n",
    "//其中Predef对象中有println,断言assert以及一些隐式类型转换方法\n",
    "Predef.println(\"hello world\")\n",
    "23 + \"123\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:04.842274Z",
     "start_time": "2019-08-25T10:20:04.651Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Name: Syntax Error.\n",
       "Message: \n",
       "StackTrace: "
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//import java.lang._ // in JVM projects, or system namespace in .NET\n",
    "//import scala._     // everything in the scala package\n",
    "//import Predef._    // everything in the Predef object"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 四，语法规则"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "1,标识符\n",
    "\n",
    "标识符由字母和数字组成，遵循驼峰命名规则。\n",
    "\n",
    "类和对象的名称以大写字母开头\n",
    "方法的名称以小写字母开头\n",
    "\n",
    "$可以被用作字母，但要慎重使用。\n",
    "因为有些特殊符号如 + 的内部表示为 $plus\n",
    "\n",
    "当存在标志符和关键字冲突时，可以加上``来避免冲突"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:08.700719Z",
     "start_time": "2019-08-25T10:20:07.916Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1+1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:09.646120Z",
     "start_time": "2019-08-25T10:20:08.607Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//和1+1等价\n",
    "1.$plus(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:11.546413Z",
     "start_time": "2019-08-25T10:20:09.176Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vec = Vector(0, 1, 4, 9)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "yield: Int = 123\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Vector(0, 1, 4, 9)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//yield为生成器保留关键字，加上``避免冲突\n",
    "val vec = for(i<- 0 to 3)yield i*i\n",
    "val `yield` = 123"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "2，注释\n",
    "多行注释用/*开头，以*/结尾包括\n",
    "单行注释用//开头"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:12.013755Z",
     "start_time": "2019-08-25T10:20:10.945Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello, world!\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<console>:1: error: illegal start of definition\n",
       "yield\n",
       "^\n",
       "lastException: Throwable = null\n",
       "hello: ()Unit\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "/* multiline comment\n",
    "some description\n",
    "more description\n",
    "*/\n",
    "def hello() {\n",
    "  // oneline comment\n",
    "  println(\"Hello, world!\");\n",
    "}\n",
    "\n",
    "hello()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3，数据类型\n",
    "\n",
    "scala中的数据类型有Byte,Short,Int,Long,Float,Double,Char,String,Boolean.\n",
    "\n",
    "以及\n",
    "\n",
    "Unit(表示无值与C语言void等同,用作无返回值的方法的返回类型),\n",
    "Null(AnyRef的子类，null是它的唯一对象),\n",
    "Nothing(所有类型的子类，它没有对象),\n",
    "Any(所有其他类的超类),\n",
    "AnyRef(所有引用类reference class的超类)\n",
    "\n",
    "等等\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](scala数据类型.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:16.115694Z",
     "start_time": "2019-08-25T10:20:13.438Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "i = 23\n",
       "l = 12\n",
       "f = 1.1\n",
       "d = 2.17\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2.17"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//数值类型\n",
    "val i = 23\n",
    "val l = 12L\n",
    "val f = 1.1F\n",
    "val d = 2.17D"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:18.442020Z",
     "start_time": "2019-08-25T10:20:14.007Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "hello world\n",
      "hello China\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "char = a\n",
       "str = hello world\n",
       "longstr = \n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "\"\n",
       "hello world\n",
       "hello China\n",
       "\"\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "//字符和字符串\n",
    "val char = 'a'\n",
    "val str = \"hello world\"\n",
    "\n",
    "val longstr = \n",
    "\"\"\"\n",
    "hello world\n",
    "hello China\n",
    "\"\"\"\n",
    "println(longstr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:19.342314Z",
     "start_time": "2019-08-25T10:20:14.600Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//判断数据类型\n",
    "str.getClass ==  classOf[String]\n",
    "str.getClass.getSimpleName\n",
    "str.isInstanceOf[Any]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:19.709933Z",
     "start_time": "2019-08-25T10:20:15.141Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "warning: there was one feature warning; re-run with -feature for details\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "123\n",
      "123\n"
     ]
    }
   ],
   "source": [
    "//强制类型转换,\n",
    "//可以用句点符号或者空格调用方法\n",
    "println(1.toString)\n",
    "println(\"123\".toInt)\n",
    "println(123 toString)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:20.068574Z",
     "start_time": "2019-08-25T10:20:15.682Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7.3\n",
      "1 world\n"
     ]
    }
   ],
   "source": [
    "//自动类型转换\n",
    "println(2.3 + 5)\n",
    "println(1 + \" world\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "4, 变量\n",
    "\n",
    "scala支持两种类型的变量，即常量val和变量var。\n",
    "常量在程序中不可以被重新指向，变量可以被重新指向新的对象。\n",
    "声明变量时可以指定类型，也可以由程序根据初始值自动推断。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:21.875988Z",
     "start_time": "2019-08-25T10:20:17.042Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = 10\n",
       "b = 10\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "10"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val a = 10\n",
    "val b:Int = 10\n",
    "// a = 15 error!\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:23.378772Z",
     "start_time": "2019-08-25T10:20:17.402Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "x = abcedf\n",
       "x = abcedf\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "abcedf"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var x = \"abc\"\n",
    "x = x + \"edf\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:24.972312Z",
     "start_time": "2019-08-25T10:20:18.573Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "m = 0\n",
       "n = 0\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//同时对多个变量进行声明\n",
    "val m,n = 0\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "5，编译执行\n",
    "\n",
    "scala代码有以下几种执行方式：\n",
    "\n",
    "(1)进入scala解释器交互式执行\n",
    "\n",
    "(2)保存成后缀名为HelloWorld.scala的脚本，然后在cmd中输入 scala HelloWorld.scala\n",
    "\n",
    "(3)使用scalac进行编译 scalac HelloWorld.scala，然后生成HelloWorld.$class和HelloWorld.class的JVM文件，再用 scala -classpath . HelloWorld 执行。\n",
    "\n",
    "(4)使用sbt或者maven等项目管理工具将项目及其依赖编译成jar包，\n",
    "使用java -jar HelloWorld.jar执行\n",
    "\n",
    "\n",
    "注意当使用第3种方法scalac把代码编译时，脚本中必须要定义object单例对象。\n",
    "并且在object对象中实现main方法作为程序入口。\n",
    "\n",
    "Appendix：\n",
    "可以使用javap HelloWorld 将反编译成java。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:25.232515Z",
     "start_time": "2019-08-25T10:20:19.939Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined object HelloWorld\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "object HelloWorld {\n",
    "   def main(args: Array[String]):Unit={\n",
    "      println(\"Hello, world!\") \n",
    "   }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:25.241483Z",
     "start_time": "2019-08-25T10:20:20.217Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Name: Syntax Error.\n",
       "Message: \n",
       "StackTrace: "
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//另存为HelloWorld.scala\n",
    "//scalac HelloWorld.scala 进行编译\n",
    "//scala -classpath . HelloWorld 执行"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "6,scala中的标点括号用法汇总\n",
    "\n",
    "(1)小括号()用来表示优先级，传入函数参数序列，以及传入容器的下标或key\n",
    "(2)中括号[]用来表示容器的元素的数值类型\n",
    "(3)大括号{}用来划分作用域，{}的返回值为最后一个语句的值。\n",
    "\n",
    "(4)句点符号.表示方法，可以用空格代替\n",
    "(5)冒号:用来说明变量的数据类型\n",
    "(6)=>用来表示匿名函数的映射关系\n",
    "(7)->用来指定映射Map中的键值关系\n",
    "(8)<-用来指定for表达式的迭代器\n",
    "(9)下划线_在scala中被用作占位符表示函数参数或作为引入package的通配符\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 五，Scala数据结构概述"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Scala中最常用的数据结构为数组Array以及collection包中的各种容器类。\n",
    "按照两个角度进行划分，容器类可以分为可变或者不可变类型，有序或者无序类型。\n",
    "\n",
    "有序的数据类型封装在 scala.collection.mutable包中，\n",
    "无序的数据类型封装在 scala.collection.immutable包中。\n",
    "\n",
    "常用的数据结构有以下一些：\n",
    "\n",
    "Array 定长数组： 有序，可变类型，长度不可变。\n",
    "\n",
    "List 列表：有序，不可变类型。\n",
    "\n",
    "ArrayBuffer 不定长数组：有序，可变类型，长度可以扩展。\n",
    "\n",
    "Set 集合：无序，不可变类型。\n",
    "\n",
    "Map 映射：无序，不可变类型。\n",
    "\n",
    "Tuple 元组：有序，不可变类型，可以存放不同数据类型元素。\n",
    "\n",
    "Option 选项：表示有可能包含值的容器，也可能不包含值。\n",
    "\n",
    "Iterator 迭代器：不属于容器，但是提供了遍历容器的方法。\n",
    "\n",
    "除了Array和ArrayBuffer默认引入的是可变类型外,其它数据结构默认引入的都是不可变的，可以显式地从scala.collection.mutable引入对应可变容器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:25.545458Z",
     "start_time": "2019-08-25T10:20:22.264Z"
    }
   },
   "outputs": [],
   "source": [
    "import scala.collection.mutable\n",
    "import scala.collection.immutable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:26.805897Z",
     "start_time": "2019-08-25T10:20:23.033Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "arr = Array(1, 2, 0)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(1, 2, 0)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//Array可变\n",
    "val arr = Array(1,2,3)\n",
    "arr(2) = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:29.064825Z",
     "start_time": "2019-08-25T10:20:23.570Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "list = List(1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//List不可变\n",
    "val list = List(1,2,3)\n",
    "list.isInstanceOf[Immutable]\n",
    "//list(2) = 0 //error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:31.036550Z",
     "start_time": "2019-08-25T10:20:24.046Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "l = ListBuffer(1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import scala.collection.mutable.ListBuffer\n",
    "val l = ListBuffer(1,2,3)\n",
    "l.isInstanceOf[Mutable]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 六，String 字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字符串的操作主要包括创建，连接，分割，替换，格式化字符串等。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，创建字符串**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-08T04:00:50.032098Z",
     "start_time": "2019-09-08T04:00:47.353Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "s1 = hello world\n",
       "s2 = hello China\n",
       "s3 = \n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "\"\n",
       "hello world\n",
       "hello China\n",
       "hello Beijing\n",
       "\"\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "val s1 = \"hello world\"\n",
    "val s2 = \"hello China\"\n",
    "val s3 = \n",
    "\"\"\"\n",
    "hello world\n",
    "hello China\n",
    "hello Beijing\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，字符串常用操作**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:33.543073Z",
     "start_time": "2019-08-25T10:20:27.376Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "hello world\n",
       "hello China\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "//+号字符串连接\n",
    "s1 +\"\\n\"+s2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:34.174377Z",
     "start_time": "2019-08-25T10:20:28.137Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "hello world hello Beijing"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//concat字符串连接\n",
    "s1.concat(\" hello Beijing\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:34.864024Z",
     "start_time": "2019-08-25T10:20:28.866Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "hello Beijing"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"hello\" concat \" \" concat \"Beijing\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:35.652715Z",
     "start_time": "2019-08-25T10:20:29.660Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//字符串长度\n",
    "s1.length"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:36.354391Z",
     "start_time": "2019-08-25T10:20:30.427Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "e"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//取某个字符\n",
    "s1(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-08T04:01:02.604078Z",
     "start_time": "2019-09-08T04:01:01.686Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "hello"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//取某个子串\n",
    "s1.slice(0,5) //也可以用substring"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:50.835509Z",
     "start_time": "2019-08-25T10:20:49.989Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//字符串比较\n",
    "s1>s2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:51.628212Z",
     "start_time": "2019-08-25T10:20:50.560Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "hello_world"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//字符串替换\n",
    "s1.replace(\" \",\"_\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:52.396058Z",
     "start_time": "2019-08-25T10:20:51.215Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(hello, world)"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//字符串分割\n",
    "s1.split(\" \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:54.338112Z",
     "start_time": "2019-08-25T10:20:51.699Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "name = Jim\n",
       "age = 18\n",
       "weight = 48.5\n",
       "s_str = I'm Jim, 18 years old, my weight is 48.5.\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "I'm Jim, 18 years old, my weight is 48.5."
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//s插值器\n",
    "val name = \"Jim\"\n",
    "val age = 18\n",
    "val weight = 48.5 \n",
    "\n",
    "val s_str = s\"I'm ${name}, ${age} years old, my weight is ${weight}.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:55.573091Z",
     "start_time": "2019-08-25T10:20:52.284Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "f_str = Jim's weight is 48.50\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Jim's weight is 48.50"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//f插值器\n",
    "val f_str = f\"${name}%s's weight is ${weight}%2.2f\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:20:56.299676Z",
     "start_time": "2019-08-25T10:20:52.835Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "raw_str = hello\\tworld\\n\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "hello\\tworld\\n"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//raw插值器\n",
    "val raw_str = raw\"hello\\tworld\\n\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 七，Array 数组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数组Array是一种可变的有序数据结构，其长度创建后是不可变的，如果要使用长度可变的数组，可以引入ArrayBuffer。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，定义数组**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:03.497212Z",
     "start_time": "2019-08-25T10:21:02.724Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = Array(1, hello, 2.12)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(1, hello, 2.12)"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//使用new进行初始化后赋值\n",
    "val a:Array[Any] = new Array[Any](3)\n",
    "a(0) = 1\n",
    "a(1) = \"hello\"\n",
    "a(2) = 2.12"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:04.572940Z",
     "start_time": "2019-08-25T10:21:03.301Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = Array(hello, world, hello, China)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(hello, world, hello, China)"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// 隐式调用apply方法实现初始化\n",
    "val a = Array(\"hello\",\"world\",\"hello\",\"China\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:05.322654Z",
     "start_time": "2019-08-25T10:21:03.848Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = Array(hello, world, hello, China)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(hello, world, hello, China)"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// 直接调用apply方法实现初始化\n",
    "val a = Array.apply(\"hello\",\"world\",\"hello\",\"China\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:06.040504Z",
     "start_time": "2019-08-25T10:21:04.326Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = Array(0, 2, 4, 6, 8)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(0, 2, 4, 6, 8)"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// 使用range方法\n",
    "val a = Array.range(0,10,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:06.680045Z",
     "start_time": "2019-08-25T10:21:04.864Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = Array(5, 6, 7, 8, 9, 10)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(5, 6, 7, 8, 9, 10)"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// 使用tabulate方法\n",
    "val a = Array.tabulate(6)(i => i + 5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:07.671640Z",
     "start_time": "2019-08-25T10:21:05.379Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b = Array(Array(0, 1), Array(1, 2))\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(Array(0, 1), Array(1, 2))"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//多维数组\n",
    "val b = Array.ofDim[String](2,2)\n",
    "for(i<-0 to 1){\n",
    "    for(j<-0 to 1){\n",
    "        b(i)(j) = (i+j).toString\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:08.499985Z",
     "start_time": "2019-08-25T10:21:05.836Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "c = Array(Array(1, 2), Array(3, 4))\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(Array(1, 2), Array(3, 4))"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//多维数组\n",
    "val c = Array(Array(1,2),Array(3,4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:09.173649Z",
     "start_time": "2019-08-25T10:21:06.332Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = Array(Array(3, 3), Array(3, 3))\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(Array(3, 3), Array(3, 3))"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//多维数组\n",
    "val a = Array.fill(2,2)(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:09.971383Z",
     "start_time": "2019-08-25T10:21:06.808Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = Array(Array(0, 1), Array(1, 2))\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(Array(0, 1), Array(1, 2))"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// 使用tabulate方法\n",
    "val a = Array.tabulate(2,2)(_+_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，数组常用操作**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数组的常用操作包括遍历，修改某些元素值，取极值，求和，排序等操作\n",
    "\n",
    "如果要增加和删除元素，需要使用 ArrayBuffer可变长数组。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:10.775842Z",
     "start_time": "2019-08-25T10:21:08.196Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "x = Array(1, 2, 1, 4, 3, 6, 7, 10, 5)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(1, 2, 1, 4, 3, 6, 7, 10, 5)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//修改元素值\n",
    "val x = Array(1,2,6,4,3,6,7,10,9)\n",
    "x(8) = 5\n",
    "x.update(2,1) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:11.850157Z",
     "start_time": "2019-08-25T10:21:08.725Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(1, 4, 3, 6, 7)"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//切片\n",
    "x.slice(2,7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:13.030633Z",
     "start_time": "2019-08-25T10:21:09.283Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sortedx = Array(1, 1, 2, 3, 4, 5, 6, 7, 10)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(1, 1, 2, 3, 4, 5, 6, 7, 10)"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//最大值,最小值,排序\n",
    "x.max\n",
    "x.min\n",
    "val sortedx = x.sorted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:14.450951Z",
     "start_time": "2019-08-25T10:21:09.648Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "x_buffer = ArrayBuffer(1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "ArrayBuffer(1, 2, 3)"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//转换成ArrayBuffer\n",
    "import scala.collection.mutable.ArrayBuffer\n",
    "val x_buffer = Array(1,2,3).toBuffer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:15.426486Z",
     "start_time": "2019-08-25T10:21:10.131Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ArrayBuffer(1, 2, 3, 4, 5, 6)"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//增加元素\n",
    "x_buffer.append(4)\n",
    "x_buffer.appendAll(Array(5,6))\n",
    "x_buffer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:16.184792Z",
     "start_time": "2019-08-25T10:21:10.513Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "x_buffer_drop = ArrayBuffer(1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "ArrayBuffer(1, 2, 3)"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//删除元素\n",
    "val x_buffer_drop = x_buffer.dropRight(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:16.478122Z",
     "start_time": "2019-08-25T10:21:10.944Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ArrayBuffer(1, 0, 2, 3, 4, 5, 6)\n"
     ]
    }
   ],
   "source": [
    "//插入元素\n",
    "x_buffer.insert(1,0)\n",
    "println(x_buffer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:18.017904Z",
     "start_time": "2019-08-25T10:21:11.288Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "4\n",
      "5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "c = Array(Array(1, 2), Array(4, 5))\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(Array(2, 3), Array(5, 6))"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//多维数组遍历\n",
    "val c = Array(Array(1,2),Array(4,5))\n",
    "c.foreach(arr => arr.foreach(println))\n",
    "c.map(arr => arr.map(_+1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 八，列表List"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表和数组相似，都是有序的结构，但列表中的元素是不可变的。\n",
    "\n",
    "并且列表的存储结构为递推的链表结构，和数组不同。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，创建列表**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:19.007765Z",
     "start_time": "2019-08-25T10:21:12.459Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "l = List(5, 7, 9, 11, 13, 15)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(5, 7, 9, 11, 13, 15)"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//指定递推关系创建\n",
    "val l = List.iterate(5,6)(x=>x+2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:19.929733Z",
     "start_time": "2019-08-25T10:21:12.722Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "l = List(0.1, 0.2, 0.3, 0.4)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(0.1, 0.2, 0.3, 0.4)"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val l = List(0.1,0.2,0.3,0.4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:21.115722Z",
     "start_time": "2019-08-25T10:21:12.962Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "l = List(0.01, 0.03, 0.05)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(0.01, 0.03, 0.05)"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//Nil为空列表\n",
    "val l:List[Double] = 0.01::0.03::0.05::Nil"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:22.363509Z",
     "start_time": "2019-08-25T10:21:13.272Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "l = List(List(0, 1), List(1, 2))\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(List(0, 1), List(1, 2))"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val l = List.tabulate(2,2)(_+_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:23.380855Z",
     "start_time": "2019-08-25T10:21:13.562Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "l = List(1, 3, 5, 7, 9)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(1, 3, 5, 7, 9)"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val l = List.range(1,10,2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，列表常用操作**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:28.248430Z",
     "start_time": "2019-08-25T10:21:27.281Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "list = List(1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(1, 2, 3)"
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var list = List(1,2,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:30.472316Z",
     "start_time": "2019-08-25T10:21:29.895Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list.length"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:32.215990Z",
     "start_time": "2019-08-25T10:21:30.691Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "list1 = List(4, 1, 2, 3)\n",
       "list2 = List(4, 1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(4, 1, 2, 3)"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//在列表前和某个元素拼接\n",
    "val list1 = 4::list\n",
    "\n",
    "val list2 = 4+:list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:33.159139Z",
     "start_time": "2019-08-25T10:21:31.561Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "list3 = List(1, 2, 3, 4)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(1, 2, 3, 4)"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//在列表后与某个元素连接\n",
    "val list3 = list:+4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:33.836229Z",
     "start_time": "2019-08-25T10:21:32.645Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//测试列表是否包含某个元素\n",
    "list.contains(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:34.933841Z",
     "start_time": "2019-08-25T10:21:33.474Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//列表头\n",
    "list.head"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:35.770705Z",
     "start_time": "2019-08-25T10:21:34.334Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "List(2, 3)"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//列表其余部分\n",
    "list.tail"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:36.553833Z",
     "start_time": "2019-08-25T10:21:35.096Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "list_new = List(1, 2, 3, 1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(1, 2, 3, 1, 2, 3)"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//列表连接\n",
    "val list_new = list:::list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:37.646945Z",
     "start_time": "2019-08-25T10:21:35.893Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "List(1, 2, 3)"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//提取前4个元素与后四个元素\n",
    "list.take(4)\n",
    "list.takeRight(4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:38.466615Z",
     "start_time": "2019-08-25T10:21:36.634Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "List(3, 2, 1)"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//列表反转\n",
    "list.reverse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:39.316166Z",
     "start_time": "2019-08-25T10:21:37.325Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "List(1, 2, 3, 4)"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//去除重复元素\n",
    "list3.distinct"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:40.127796Z",
     "start_time": "2019-08-25T10:21:37.996Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "List()"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//过滤\n",
    "list3.filter(_>5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:40.674816Z",
     "start_time": "2019-08-25T10:21:38.724Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//测试是否每个元素都满足条件，返回Boolean\n",
    "list2.forall(_>0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 九，集合"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合是一种不可变的类型，并且是无顺序的，适合查找某个元素是否在集合中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:41.629662Z",
     "start_time": "2019-08-25T10:21:41.046Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "s = Set(1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Set(1, 2, 3)"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var s = Set(1,2,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:42.640508Z",
     "start_time": "2019-08-25T10:21:41.777Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Set(1, 2, 3, 5)"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//虽然集合不可变，但是s可变，添加元素5得到新的集合并将s指向它\n",
    "s += 5\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:43.418490Z",
     "start_time": "2019-08-25T10:21:42.410Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Set(1, 2, 3)"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//删除元素\n",
    "s - 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:44.119468Z",
     "start_time": "2019-08-25T10:21:43.053Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.contains(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:44.833992Z",
     "start_time": "2019-08-25T10:21:43.680Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Set(5, 1, 2, 3, 4)"
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.union(Set(3,4,5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:45.545728Z",
     "start_time": "2019-08-25T10:21:44.320Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Set(2, 3)"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s intersect Set(2,3,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:46.316809Z",
     "start_time": "2019-08-25T10:21:44.943Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Set(2, 3)"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s & Set(2,3,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:47.007384Z",
     "start_time": "2019-08-25T10:21:45.627Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Set(5, 1, 2, 3, 4)"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s | Set(2,3,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十，Map 映射"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "映射和python中的字典很像，但是scala中的Map是一种不可变类型。\n",
    "\n",
    "如果需要使用可变的Map,需要从scala.collection.mutable引入。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，创建Map**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:50.131722Z",
     "start_time": "2019-08-25T10:21:49.061Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "city = Map(WUHAN -> WH, XIAMEN -> XM)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Map(WUHAN -> WH, XIAMEN -> XM)"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//创建空列表，尽管Map不可变但city是可变的\n",
    "//添加元素得到新的Map并指向它\n",
    "var city:Map[String,String] = Map()\n",
    "city += (\"WUHAN\"->\"WH\")\n",
    "city += (\"XIAMEN\"->\"XM\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:51.105072Z",
     "start_time": "2019-08-25T10:21:49.837Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "city = Map(WUHAN -> WH, XIAMEN -> XM)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Map(WUHAN -> WH, XIAMEN -> XM)"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//隐式使用apply\n",
    "var city = Map(\"WUHAN\"->\"WH\",\"XIAMEN\"->\"XM\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，Map常用操作**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Map常用操作包括查找，合并，遍历等操作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:53.764608Z",
     "start_time": "2019-08-25T10:21:52.674Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "city = Map(WUHAN -> WH, XIAMEN -> XM)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "WH"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var city = Map(\"WUHAN\"->\"WH\",\"XIAMEN\"->\"XM\")\n",
    "city(\"WUHAN\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:54.432695Z",
     "start_time": "2019-08-25T10:21:53.367Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "result = NOTFOUND\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "NOTFOUND"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//查找\n",
    "val result = if (city.contains(\"SHANGHAI\")) city(\"WUHAN\") \n",
    "else \"NOTFOUND\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:55.137254Z",
     "start_time": "2019-08-25T10:21:54.037Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "result = NOTFOUND\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "NOTFOUND"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//用get去查找\n",
    "val result = city.get(\"BEIJING\").getOrElse(\"NOTFOUND\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:55.573932Z",
     "start_time": "2019-08-25T10:21:54.752Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Map(WUHAN -> WH, XIAMEN -> XM, SHANGHAI -> SH)\n"
     ]
    }
   ],
   "source": [
    "//合并\n",
    "println(city ++ Map(\"SHANGHAI\"->\"SH\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:56.637290Z",
     "start_time": "2019-08-25T10:21:55.378Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(WUHAN,WH)\n",
      "(XIAMEN,XM)\n"
     ]
    }
   ],
   "source": [
    "//遍历\n",
    "for((k,v)<-city) println(k,v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:57.106838Z",
     "start_time": "2019-08-25T10:21:56.147Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WUHAN\n",
      "XIAMEN\n"
     ]
    }
   ],
   "source": [
    "//遍历key\n",
    "for(k<-city.keys) println(k)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:21:58.161016Z",
     "start_time": "2019-08-25T10:21:56.777Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Map(WUHAN -> WC, SHANGHAI -> MD)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "city = Map(WUHAN -> WC, SHANGHAI -> MD)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Map(WUHAN -> WC, SHANGHAI -> MD)"
      ]
     },
     "execution_count": 108,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//导入可变对象后可以增加和修改键值对\n",
    "import scala.collection.mutable.Map\n",
    "\n",
    "val city = Map(\"WUHAN\"->\"WH\")\n",
    "city(\"WUHAN\") = \"WC\"\n",
    "city(\"SHANGHAI\") = \"MD\"\n",
    "println(city)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十一，元组Tuple\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "元组也是一种不可变的数据结构，其特点是可以存储类型不同的对象。\n",
    "\n",
    "默认情况下元组的最长长度为22。\n",
    "\n",
    "使用圆括号括号括起来的几个对象就构成了元组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，创建元组**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:00.951685Z",
     "start_time": "2019-08-25T10:22:00.370Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "t = (123,hello,123.2,true)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(123,hello,123.2,true)"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val t = (123,\"hello\",123.2f,true)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:01.696902Z",
     "start_time": "2019-08-25T10:22:00.932Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "t = (1,3.14,hello)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(1,3.14,hello)"
      ]
     },
     "execution_count": 110,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val t = new Tuple3(1, 3.14, \"hello\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，使用元组**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:03.308551Z",
     "start_time": "2019-08-25T10:22:02.725Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n",
      "hello\n",
      "123.2\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "t = (123,hello,123.2,true)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(123,hello,123.2,true)"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val t = (123,\"hello\",123.2f,true)\n",
    "println(t._1)\n",
    "println(t._2)\n",
    "println(t._3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十二，迭代器 Iterator"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "迭代器不是一种容器，但是它提供了一种访问容器的方法。\n",
    "迭代器主要有hasNext和next两个常用方法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，创建迭代器**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:06.501449Z",
     "start_time": "2019-08-25T10:22:05.817Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "iter = non-empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "non-empty iterator"
      ]
     },
     "execution_count": 112,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//直接创建迭代器\n",
    "val iter = Iterator(\"baidu\",\"alibaba\",\"tencent\",\"huawei\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:07.937542Z",
     "start_time": "2019-08-25T10:22:06.318Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "set = Set(hello, 123, true, 3.14)\n",
       "iter = non-empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "non-empty iterator"
      ]
     },
     "execution_count": 113,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//容器转换成迭代器\n",
    "val set = Set(\"hello\",123,true,3.14)\n",
    "val iter = set.toIterator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:09.036670Z",
     "start_time": "2019-08-25T10:22:06.882Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "group = non-empty iterator\n",
       "slide = non-empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "non-empty iterator"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//容器通过分组和滑动窗口得到迭代器\n",
    "val group = set.grouped(3)\n",
    "val slide = set.sliding(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "**2，使用迭代器**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:10.468485Z",
     "start_time": "2019-08-25T10:22:08.895Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "baidu\n",
      "alibaba\n",
      "tencent\n",
      "huawei\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "iter = empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "false"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val iter = Iterator(\"baidu\",\"alibaba\",\"tencent\",\"huawei\")\n",
    "println(iter.next)\n",
    "println(iter.next)\n",
    "println(iter.next)\n",
    "println(iter.next)\n",
    "iter.hasNext"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:11.660622Z",
     "start_time": "2019-08-25T10:22:09.334Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "123\n",
      "true\n",
      "3.14\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "set = Set(hello, 123, true, 3.14)\n",
       "iter = empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "empty iterator"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//for表达式遍历Iterator\n",
    "val set = Set(\"hello\",123,true,3.14)\n",
    "val iter = set.toIterator\n",
    "for(x<-iter) println(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:12.738357Z",
     "start_time": "2019-08-25T10:22:09.794Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "123\n",
      "true\n",
      "3.14\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "set = Set(hello, 123, true, 3.14)\n",
       "iter = empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "empty iterator"
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//while语句遍历Iterator\n",
    "val set = Set(\"hello\",123,true,3.14)\n",
    "val iter = set.toIterator\n",
    "while(iter.hasNext) println(iter.next)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:14.009182Z",
     "start_time": "2019-08-25T10:22:10.301Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "hello\n",
      "world\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "iter1 = empty iterator\n",
       "iter2 = empty iterator\n",
       "iter = empty iterator\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "empty iterator"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//迭代器合并\n",
    "val iter1 = Iterator(1,2,3)\n",
    "val iter2 = Iterator(\"hello\",\"world\")\n",
    "val iter = iter1 ++ iter2\n",
    "for(x<-iter)println(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十三，Option 选项"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Option表示有可能包含值，也可能不包含值的容器。\n",
    "\n",
    "它有两个子类，一个是Some，一个是对象None。\n",
    "\n",
    "它的主要方法是getOrElse 和isEmpty。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:15.841218Z",
     "start_time": "2019-08-25T10:22:14.496Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "opt1 = Some(hello)\n",
       "opt2 = None\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "class scala.None$"
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val opt1:Option[String] = Some(\"hello\")\n",
    "val opt2:Option[String] = None\n",
    "\n",
    "opt1.getClass\n",
    "opt2.getClass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:18.087032Z",
     "start_time": "2019-08-25T10:22:16.568Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "d = Map(NANCHANG -> NC, BEIJING -> BJ)\n",
       "opt = None\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val d = Map(\"BEIJING\"->\"BJ\",\"NANCHANG\"->\"NC\")\n",
    "val opt = d.get(\"SHANGHAI\")\n",
    "opt.getOrElse(\"NOTFOUND\")\n",
    "opt.isEmpty"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十四，选择结构\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "scala的选择结构主要通过if语句以及match语句实现。\n",
    "match 语句相当于多分支结构，可以使用模式匹配。\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，if选择语句**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:20.631807Z",
     "start_time": "2019-08-25T10:22:19.529Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = 2\n",
       "b = 3\n",
       "m = 3\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//if...else...语句\n",
    "val a = 2\n",
    "val b = 3\n",
    "var m = a\n",
    "if(a>b){\n",
    "    m = a\n",
    "}else{\n",
    "    m = b}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:21.726776Z",
     "start_time": "2019-08-25T10:22:20.425Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = 2\n",
       "b = 3\n",
       "m = 3\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//单行if语句\n",
    "val a = 2\n",
    "val b = 3\n",
    "var m =  if(a>b) a else b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:23.263312Z",
     "start_time": "2019-08-25T10:22:21.180Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a = 2\n",
       "b = 3\n",
       "c = 1\n",
       "m = 3\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//if...else if...else if...else...\n",
    "val a = 2\n",
    "val b = 3\n",
    "val c = 1\n",
    "\n",
    "var m = 0\n",
    "if(a>b&&a>c){\n",
    "    m = a\n",
    "}else if(b>a&&b>c){\n",
    "    m = b\n",
    "}else{\n",
    "    m = c\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:23.425927Z",
     "start_time": "2019-08-25T10:22:21.966Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "true\n",
      "false\n",
      "true\n"
     ]
    }
   ],
   "source": [
    "//逻辑运算符\n",
    "println(true || false)\n",
    "println(true && false)\n",
    "println(!false)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，match模式匹配**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:24.632552Z",
     "start_time": "2019-08-25T10:22:23.164Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "one\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "a = 1\n",
       "x = one\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "one"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//match多分支结构\n",
    "val a = 1\n",
    "val x = a match{\n",
    "    case 1 => \"one\"\n",
    "    case 2 => \"two\"\n",
    "    case _ => \"many\"   \n",
    "} \n",
    "println(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:25.714466Z",
     "start_time": "2019-08-25T10:22:23.898Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "elem = hello\n",
       "x = hello is a string value\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "hello is a string value"
      ]
     },
     "execution_count": 126,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//match类型匹配\n",
    "//注意将选择器声明为Any类型\n",
    "\n",
    "val elem:Any = \"hello\"\n",
    "val x = elem match{\n",
    "    case i:Int => i + \" is a int value\"\n",
    "    case d:Double => d + \" is a double value\"\n",
    "    case \"spark\" => \"spark is found\"\n",
    "    case s:String => s + \" is a string value\"\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:26.079346Z",
     "start_time": "2019-08-25T10:22:24.397Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 is even\n",
      "2 is odd\n",
      "3 is even\n",
      "4 is odd\n"
     ]
    }
   ],
   "source": [
    "//match添加guard语句\n",
    "for(elem <- List(1,2,3,4)){\n",
    "    elem match{\n",
    "        case _ if (elem%2 ==0) => println(elem + \" is odd\")\n",
    "        case _ => println(elem + \" is even\")\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:28.154720Z",
     "start_time": "2019-08-25T10:22:25.049Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hi Alice!\n",
      "Hi,Bob!\n",
      "Age: 20 year, name: charlie?\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined class Person\n",
       "alice = Person(Alice,17)\n",
       "bob = Person(Bob,19)\n",
       "charlie = Person(charlie,20)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Person(charlie,20)"
      ]
     },
     "execution_count": 128,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//match使用case类进行模式匹配\n",
    "//case例是一种特殊的类，经过了优化以用于模式匹配\n",
    "\n",
    "//声明case例\n",
    "case class Person(name: String, age: Int)\n",
    "val alice = new Person(\"Alice\",17)\n",
    "val bob = Person(\"Bob\",19)\n",
    "val charlie = Person(\"charlie\",20)\n",
    "\n",
    "for (person <- List(alice, bob, charlie)) {\n",
    "    person match {\n",
    "        case Person(\"Alice\", 17) => println(\"Hi Alice!\")\n",
    "        case p:Person if(p.name ==\"Bob\") => \n",
    "        println(s\"Hi,${p.name}!\")\n",
    "        case Person(name, age) =>\n",
    "        println(\"Age: \" + age + \" year, name: \" + name + \"?\")\n",
    "        }\n",
    " }\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十五，循环结构"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "循环结构主要是 for循环和while循环,此外还可以使用for推导式。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，for循环**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:30.653922Z",
     "start_time": "2019-08-25T10:22:28.983Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "l = List(1, 2, 8, 6, 4)\n",
       "max_l = 8\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 129,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//求一个列表中的最大元素\n",
    "val l = List(1,2,8,6,4)\n",
    "var max_l = l(0)\n",
    "for(i <- l){\n",
    "    max_l = if(max_l<i) i else max_l\n",
    "}\n",
    "println(max_l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2, while循环**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:31.819105Z",
     "start_time": "2019-08-25T10:22:29.949Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(5050,101)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "s = 5050\n",
       "i = 101\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "101"
      ]
     },
     "execution_count": 130,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//1到100求和\n",
    "var s = 0\n",
    "var i = 1\n",
    "while(i<=100){\n",
    "    s += i\n",
    "    i += 1\n",
    "}\n",
    "println(s,i)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3,循环控制**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:32.679664Z",
     "start_time": "2019-08-25T10:22:30.986Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "helloworld\n",
      "hello"
     ]
    },
    {
     "data": {
      "text/plain": [
       "s = hello world\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "loop: ()Unit\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "hello world"
      ]
     },
     "execution_count": 131,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//scala中默认没有breaks和continue关键字\n",
    "//可以用return和带if的循环生成器实现对应功能\n",
    "val s = \"hello world\"\n",
    "\n",
    "//replace continue by if guard\n",
    "for(i<-s if i!=' ') print(i)\n",
    "print('\\n')\n",
    "\n",
    "//replace break by return\n",
    "def loop():Unit = {\n",
    "    for(i<-s){\n",
    "        if(i==' ') return\n",
    "        print(i)\n",
    "    }\n",
    "}\n",
    "loop()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**4，for表达式的高级用法**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:32.706866Z",
     "start_time": "2019-08-25T10:22:32.085Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Name: Syntax Error.\n",
       "Message: \n",
       "StackTrace: "
      ]
     },
     "execution_count": 132,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//在Scala里，一个for表达式可以包含1个或多个「生成器」(Generator)，\n",
    "//其中，每个生成器可以包含0个或多个「守卫」(Guard)，\n",
    "//以及0个或多个「定义」(Definition)。\n",
    "//以及一个可选的yield子句。\n",
    "\n",
    "//不带yield子句的for表达式叫做for循环，带有yield子句的 for表达式叫做推导式,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:33.128828Z",
     "start_time": "2019-08-25T10:22:32.608Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "4\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "// 双重for循环带1个if守卫\n",
    "for(i <- 1 to 3; j<- i to 3 if i!=j) println(i+j)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:33.764361Z",
     "start_time": "2019-08-25T10:22:33.095Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3 4 5 6 7 8 9 10 8 10 12 14 16 18 20 15 18 21 24 27 30 "
     ]
    }
   ],
   "source": [
    "// 双重for循环带1个if守卫带1个定义\n",
    "for(i <- 1 to 3; a = i+2;j <-a to 10 if i!= j) print(i*j+\" \") "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:34.645117Z",
     "start_time": "2019-08-25T10:22:33.599Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vec = Array(1, 2, 0, 1)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(1, 2, 0, 1)"
      ]
     },
     "execution_count": 135,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// for推导式 1个生成器\n",
    "val vec = for(i<- Array.range(1,5)) yield i%3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:36.664882Z",
     "start_time": "2019-08-25T10:22:34.119Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "boys = Array(Jim, LiLei)\n",
       "girls = Array(Ann, XiaoHong)\n",
       "pairs = Array((Jim,Ann), (Jim,XiaoHong), (LiLei,Ann), (LiLei,XiaoHong))\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array((Jim,Ann), (Jim,XiaoHong), (LiLei,Ann), (LiLei,XiaoHong))"
      ]
     },
     "execution_count": 136,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//for推导式 2个生成器\n",
    "val boys = Array(\"Jim\",\"LiLei\")\n",
    "val girls = Array(\"Ann\",\"XiaoHong\")\n",
    "val pairs = for(b <- boys;g <- girls;pair = (b,g)) yield pair"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:38.731657Z",
     "start_time": "2019-08-25T10:22:34.599Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "boys = Array(Jim, LiLei)\n",
       "girls = Array(Ann, XiaoHong)\n",
       "pairs = Array((Jim,Ann), (Jim,XiaoHong), (LiLei,Ann), (LiLei,XiaoHong))\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array((Jim,Ann), (Jim,XiaoHong), (LiLei,Ann), (LiLei,XiaoHong))"
      ]
     },
     "execution_count": 137,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//for推导式 \n",
    "//可以将生成器放在花括号中\n",
    "val boys = Array(\"Jim\",\"LiLei\")\n",
    "val girls = Array(\"Ann\",\"XiaoHong\")\n",
    "val pairs = for{\n",
    "    b<-boys\n",
    "    g<-girls\n",
    "    pair = (b,g)\n",
    "} yield pair\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十六，异常捕获"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "异常捕获的语句是 try...catch...finally...\n",
    "此外还可以用throw抛出异常\n",
    "如：throw new IllegalArgumentException"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:38.928445Z",
     "start_time": "2019-08-25T10:22:36.191Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined object Test\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Missing file exception\n",
      "Exiting finally...\n"
     ]
    }
   ],
   "source": [
    "import java.io.FileReader\n",
    "import java.io.FileNotFoundException\n",
    "import java.io.IOException\n",
    "\n",
    "object Test {\n",
    "   def main() {\n",
    "      try {\n",
    "         val f = new FileReader(\"input.txt\")\n",
    "      } catch {\n",
    "         case ex: FileNotFoundException => {\n",
    "            println(\"Missing file exception\")\n",
    "         }\n",
    "         case ex: IOException => {\n",
    "            println(\"IO Exception\")\n",
    "         }\n",
    "      } finally {\n",
    "         println(\"Exiting finally...\")\n",
    "      }\n",
    "   }\n",
    "}\n",
    "\n",
    "Test.main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十七，方法定义"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "scala中的函数和方法是不同的概念。方法使用def关键字定义。\n",
    "\n",
    "而函数相当于Python中的匿名函数，可以像变量一样定义。\n",
    "\n",
    "可以通过关键字def定义方法。\n",
    "\n",
    "此处介绍def定义方法的语法。\n",
    "\n",
    "def functionName(args list):[return type] = {\n",
    "\n",
    "   function body\n",
    "   \n",
    "   return expr\n",
    "   \n",
    "}\n",
    "\n",
    "当方法的输出类型可以推断时，可以省去“:[return type]= ”。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:39.642291Z",
     "start_time": "2019-08-25T10:22:38.352Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "my_abs: (arg: Double)Double\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 139,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//完整定义的方法\n",
    "def my_abs(arg:Double):Double = {\n",
    "    if(arg>0) arg else -arg\n",
    "}\n",
    "my_abs(-2.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:40.235552Z",
     "start_time": "2019-08-25T10:22:38.841Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "my_abs: (arg: Double)Double\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 140,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//当方法的输出类型可以推断时，可以省去“:[return type]”\n",
    "def my_abs(arg:Double) = {\n",
    "    if(arg>0) arg else -arg\n",
    "}\n",
    "my_abs(-2.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:40.428335Z",
     "start_time": "2019-08-25T10:22:39.393Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "printMe: ()Unit\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello, Scala!\n"
     ]
    }
   ],
   "source": [
    "//没有返回值的方法,可以用Unit作为返回值类型\n",
    "def printMe():Unit = {\n",
    "  println(\"Hello, Scala!\")\n",
    "}\n",
    "printMe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:41.227864Z",
     "start_time": "2019-08-25T10:22:39.857Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "addInt: (a: Int, b: Int)Int\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 142,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//使用默认参数\n",
    "def addInt( a:Int=5, b:Int=7 ):Int = {\n",
    "      var sum:Int = a + b\n",
    "      return sum\n",
    "}\n",
    "addInt()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 143,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:42.178098Z",
     "start_time": "2019-08-25T10:22:40.301Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "world\n",
      "scala\n",
      "hello\n",
      "spark\n",
      "scala\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "args = List(hello, spark, scala)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "printStrings: (args: String*)Unit\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(hello, spark, scala)"
      ]
     },
     "execution_count": 143,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//使用可变参数\n",
    "def printStrings(args:String* ) {\n",
    "      for( arg <- args )println(arg )\n",
    "      }\n",
    "printStrings(\"hello\",\"world\",\"scala\")\n",
    "val args = List(\"hello\",\"spark\",\"scala\")\n",
    "\n",
    "//调用List的各个元素作为参数序列时，加上：_*说明\n",
    "printStrings(args:_*)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:42.508909Z",
     "start_time": "2019-08-25T10:22:40.827Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined object Test\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of a : 7\n",
      "Value of b : 5\n"
     ]
    }
   ],
   "source": [
    "//调用方法时指定参数名\n",
    "object Test {\n",
    "   def main(){\n",
    "        printInt(b=5, a=7);\n",
    "   }\n",
    "   def printInt( a:Int, b:Int ) = {\n",
    "      println(\"Value of a : \" + a );\n",
    "      println(\"Value of b : \" + b );\n",
    "   }\n",
    "}\n",
    "Test.main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:43.349561Z",
     "start_time": "2019-08-25T10:22:41.263Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "factorial: (n: BigInt)BigInt\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2432902008176640000"
      ]
     },
     "execution_count": 145,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//递归函数\n",
    "def factorial(n: BigInt):BigInt = {  \n",
    "      if (n <= 1) 1  else n * factorial(n - 1)\n",
    "   }\n",
    "factorial(20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十八，函数定义\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "scala中的函数是一等公民，可以像变量一样定义和使用。\n",
    "\n",
    "和变量一样，函数具有类型和值。\n",
    "\n",
    "函数的类型是函数的参数和返回值的类型映射关系，\n",
    "如 Int => Unit; (Array[Int],String) => Int 。\n",
    "\n",
    "函数的值是函数的参数和返回值的取值映射关系，\n",
    "如 x => x+1;  x,y => x+y 。\n",
    "\n",
    "\n",
    "此外，当函数表达式中引用了非参数的变量时，这种函数叫做闭包。\n",
    "\n",
    "闭包的特性是每次调用它时都会将外部的开放的变量封闭成局部值。\n",
    "\n",
    "闭包的返回值受外部变量取值变化的影响。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:44.454494Z",
     "start_time": "2019-08-25T10:22:43.170Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "f = > Int = <function1>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//完整定义\n",
    "//val f:(Int=>Int) = ((x:Int)=> x+1)\n",
    "val f:Int=>Int = (x:Int) => x+1\n",
    "f(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:45.541670Z",
     "start_time": "2019-08-25T10:22:43.597Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "f = > Int = <function1>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 147,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//可以推断函数类型，予以省略\n",
    "val f = (x:Int) => x+1\n",
    "f(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:46.212421Z",
     "start_time": "2019-08-25T10:22:44.041Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 148,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//可以省略函数名,匿名函数\n",
    "((x:Int) => x+1)(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:46.774678Z",
     "start_time": "2019-08-25T10:22:44.540Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 149,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//可以进一步用占位符代替参数\n",
    "((_:Int) + 1)(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:47.355905Z",
     "start_time": "2019-08-25T10:22:44.987Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 150,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//每个参数依次填充占位符位置\n",
    "((_:Int)+(_:Int))(1,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:48.641969Z",
     "start_time": "2019-08-25T10:22:45.452Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n",
      "5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "a = 2\n",
       "f = > Int = <function1>\n",
       "a = 2\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//闭包示范\n",
    "var a = 1\n",
    "val f = (x:Int)=> x+a\n",
    "println(f(3))\n",
    "a = 2\n",
    "println(f(3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<function1>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "f = > Double = <function1>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "my_abs: (arg: Double)Double\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "> Double = <function1>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//方法转函数，在方法名后面空一格, 加个下划线即可\n",
    "\n",
    "def my_abs(arg:Double) = {\n",
    "    if(arg>0) arg else -arg\n",
    "}\n",
    "\n",
    "val f = my_abs _\n",
    "\n",
    "println(f)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十九，高阶函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "scala支持非常强大的函数式编程风格。\n",
    "\n",
    "函数式编程风格的特点不显式使用循环，而是利用高阶函数调用普通函数在数据上进行遍历操作。\n",
    "\n",
    "高阶函数即可以传入函数作为其参数的函数。\n",
    "\n",
    "scala的Array和容器中的各种数据结构内置有非常丰富的高阶函数。\n",
    "\n",
    "常用的包括:map,flatMap,filter,foreach,forall,reduce,fold 。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:49.508737Z",
     "start_time": "2019-08-25T10:22:47.298Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "arr = Array(1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(2, 4, 6)"
      ]
     },
     "execution_count": 152,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//map 遍历作用 代替for推导式\n",
    "val arr = Array(1,2,3)\n",
    "arr.map(x=>x*2) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:51.837068Z",
     "start_time": "2019-08-25T10:22:47.801Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "strlist = List(hello world, hello China)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "List(hello, world, hello, China)"
      ]
     },
     "execution_count": 153,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//flatMap 遍历作用并压平\n",
    "val strlist = List(\"hello world\",\"hello China\")\n",
    "strlist.flatMap(x => x.split(\" \"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:53.565377Z",
     "start_time": "2019-08-25T10:22:52.651Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "s = Set(haha, hehe, xixi, wuwu)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Set(haha, hehe)"
      ]
     },
     "execution_count": 154,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//filter过滤\n",
    "val s = Set(\"haha\",\"hehe\",\"xixi\",\"wuwu\")\n",
    "s.filter(_.contains(\"h\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:54.457844Z",
     "start_time": "2019-08-25T10:22:53.295Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "XIAN\n",
      "SHANGHAI\n",
      "BEIJING\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "d = Map(XIAN -> XA, SHANGHAI -> SH, BEIJING -> BJ)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Map(XIAN -> XA, SHANGHAI -> SH, BEIJING -> BJ)"
      ]
     },
     "execution_count": 155,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//foreach 无返回值 代替for循环\n",
    "val d = Map(\"BEIJING\"->\"BJ\",\"SHANGHAI\"->\"SH\",\"XIAN\"->\"XA\")\n",
    "//d.foreach(println)\n",
    "d.foreach(t=>println(t._1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:55.629935Z",
     "start_time": "2019-08-25T10:22:53.865Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vec = Range(-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "false"
      ]
     },
     "execution_count": 156,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//forall 测试是否全部满足条件\n",
    "val vec = -1 to 10\n",
    "vec.forall(_>0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:56.625221Z",
     "start_time": "2019-08-25T10:22:54.368Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "arr = Array(1, 2, 3, 4, 5)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "15"
      ]
     },
     "execution_count": 157,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//reduce 归约\n",
    "val arr = Array(1,2,3,4,5)\n",
    "arr.reduce(_+_)\n",
    "arr.reduceLeft(_+_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 158,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:57.504961Z",
     "start_time": "2019-08-25T10:22:54.902Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "arr = Array(1, 2, 3, 4, 5)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "1200"
      ]
     },
     "execution_count": 158,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//fold 和reduce相似,只是要传入第一个参数\n",
    "val arr = Array(1,2,3,4,5)\n",
    "arr.fold(10)(_*_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十，类的定义\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "scala中用关键字class定义普通类, 用abstract class定义抽象类，\n",
    "\n",
    "用case class定义样例类,用object定义单例对象，用trait定义特征。\n",
    "\n",
    "我们先看普通类的定义和实例化。\n",
    "\n",
    "类的定义中可以用private声明为私有属性和私有方法，只允许在类的作用域访问，不允许在类的外部访问。\n",
    "\n",
    "可以用protected声明为受保护的属性和方法，只允许在类作用域及其子类作用域中访问。\n",
    "\n",
    "其余属性和方法默认为公有属性和公有方法，可以在类的作用域外访问。\n",
    "\n",
    "此外还可以在private或protected后面用方括号加上作用域保护，表示方括号中的类和对象不受访问限制。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "scala有3中定义类的风格，java风格，简写风格，和case类风格。\n",
    "\n",
    "简写风格中可以在类声明中的参数前加上val即表示为类的属性，省去属性的绑定。\n",
    "\n",
    "case类本来设计用来进行模式匹配，自带apply和unapply方法，并且自带Object伴生对象，实例化时可以不用new关键字。\n",
    "\n",
    "case类不仅可以支持模式匹配，普通类支持的功能它都支持。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，Java风格**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 159,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:58.109722Z",
     "start_time": "2019-08-25T10:22:58.011Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined class Counter\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "//一个计数器类范例\n",
    "class Counter{\n",
    "    private var value = 0\n",
    "    def increment():Unit = {\n",
    "        value += 1\n",
    "    }\n",
    "    def current = value\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:59.363476Z",
     "start_time": "2019-08-25T10:22:58.482Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "myCounter = Counter@7330ad82\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 160,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val myCounter = new Counter\n",
    "myCounter.increment()\n",
    "myCounter.current"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 161,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:22:59.547511Z",
     "start_time": "2019-08-25T10:22:58.973Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined class Dog\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "//一个Dog类范例\n",
    "class Dog(n:String,w:Double,b:String,a:Int){\n",
    "    var name = n\n",
    "    var breed  = b\n",
    "    private var weight = w\n",
    "    private var age = a\n",
    "    \n",
    "    def run(){\n",
    "        println(name + \" is running...\")\n",
    "    }\n",
    "    \n",
    "    def bark(){\n",
    "        println(\"Bowwow,Bowwow,Bowwow...\")\n",
    "    }\n",
    "    def sleep(){\n",
    "        println(\"Zzz...Zzz...Zzz...\")\n",
    "    }\n",
    "    def eat(food:String){\n",
    "        printf(\"%s is eatting %s...\\n\",name,food)\n",
    "    }\n",
    "    private def think(){\n",
    "        println(\"I feel myself a hero and very handsome !\")\n",
    "    }\n",
    "    def speak(words:String = \"\"){\n",
    "        think()\n",
    "        println(words)\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:23:00.250610Z",
     "start_time": "2019-08-25T10:22:59.520Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "snoopy\n",
      "snoopy is running...\n",
      "snoopy is eatting fish...\n",
      "I feel myself a hero and very handsome !\n",
      "hahaha\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "snoopy = Dog@5e3c7da6\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Dog@5e3c7da6"
      ]
     },
     "execution_count": 162,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val snoopy = new Dog(\"snoopy\",12.6,\"Husky\",6)\n",
    "println(snoopy.name)\n",
    "snoopy.run\n",
    "snoopy.eat(\"fish\")\n",
    "snoopy.speak(\"hahaha\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 163,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:23:00.822114Z",
     "start_time": "2019-08-25T10:22:59.999Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dog\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 163,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//获取对象信息\n",
    "println(snoopy.getClass.getSimpleName)\n",
    "snoopy.isInstanceOf[AnyRef]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，简写风格**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 164,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:23:01.334140Z",
     "start_time": "2019-08-25T10:23:00.984Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Kitty\n",
      "miaow...miaow...miaow...\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined class Cat\n",
       "kitty = Cat@1f2a83b0\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Cat@1f2a83b0"
      ]
     },
     "execution_count": 164,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//简写风格\n",
    "class Cat(val name:String,private val age:Int){\n",
    "    def call  {\n",
    "        println(\"miaow...miaow...miaow...\")\n",
    "    }\n",
    "}\n",
    "val kitty = new Cat(\"Kitty\",2)\n",
    "println(kitty.name)\n",
    "kitty.call"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3，case类风格**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:23:02.667029Z",
     "start_time": "2019-08-25T10:23:01.983Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "miaow...miaow...miaow...\n",
      "Kitty\n",
      "12.0\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined class Cat\n",
       "kitty = Cat(Kitty,12.0,3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Cat(Kitty,12.0,3)"
      ]
     },
     "execution_count": 165,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//case类风格,最简洁\n",
    "case class Cat(name:String,weight:Double,private val age:Int){\n",
    "    def call() = {println(\"miaow...miaow...miaow...\")}\n",
    "}\n",
    "\n",
    "val kitty = Cat(\"Kitty\",12.0,3)\n",
    "kitty.call()\n",
    "println(kitty.name)\n",
    "println(kitty.weight)\n",
    "//kitty.age"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十一，getter和setter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "私有属性可以通过getter和setter方法比较安全地访问和修改。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 170,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:23:40.340400Z",
     "start_time": "2019-08-25T10:23:39.806Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "4\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined class Counter\n",
       "myCounter = Counter@1d1f3dee\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "myCounter.value: Int = 4\n",
       "myCounter.value: Int = 4\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Counter@1d1f3dee"
      ]
     },
     "execution_count": 170,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//getter方法通过定义无参数的方法实现\n",
    "//setter方法通过定义带参数的命名中有下划线的方法实现\n",
    "class Counter{\n",
    "    private var privatevalue = 0\n",
    "    def value = privatevalue\n",
    "    def value_= (newValue:Int){\n",
    "        if(newValue>0)privatevalue = newValue\n",
    "    }\n",
    "    def increment(){privatevalue += 1}\n",
    "}\n",
    "\n",
    "val myCounter = new Counter\n",
    "myCounter.increment\n",
    "println(myCounter.value)\n",
    "myCounter.value = 2\n",
    "println(myCounter.value)\n",
    "myCounter.value = 4\n",
    "println(myCounter.value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十二，构造器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Scala的类包括一个主构造器和若干个(0个或多个)辅助构造器。\n",
    "主构造器即定义类时传参并用来初始化对象属性的构造器，它是隐含的。\n",
    "辅助构造器的名称为this，每个辅助构造器都必须调用一个此前已经定义好的主构造器或辅助构造器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 171,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:23:48.199274Z",
     "start_time": "2019-08-25T10:23:46.885Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n",
      "Timer\n",
      "Numer\n",
      "2\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined class Counter\n",
       "myCounter1 = Counter@3aca9db3\n",
       "myCounter2 = Counter@1182a3a8\n",
       "myCounter3 = Counter@35516ec6\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Counter@35516ec6"
      ]
     },
     "execution_count": 171,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//构造器范例\n",
    "class Counter(){\n",
    "    private var value = 0\n",
    "    var name = \"None\"\n",
    "    var mode = 1\n",
    "    def this(name:String){\n",
    "        this()\n",
    "        this.name = name\n",
    "    }\n",
    "    def this(name:String,mode:Int){\n",
    "        this(name)\n",
    "        this.mode = mode\n",
    "    }\n",
    "    def increment(){value += 1}\n",
    "    def current() = value\n",
    "}\n",
    "\n",
    "val myCounter1 = new Counter\n",
    "println(myCounter1.name)\n",
    "val myCounter2 = new Counter(name=\"Timer\")\n",
    "println(myCounter2.name)\n",
    "val myCounter3 = new Counter(name=\"Numer\",mode = 2)\n",
    "println(myCounter3.name)\n",
    "println(myCounter3.mode)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十三，单例对象和伴生对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Object定义的对象为单例对象，可以直接使用无需实例化。\n",
    "\n",
    "如果在一个文件有一个Object和一个Class是同名的，那么这个Object称为这个Class的伴生对象，这个Class称为这个Object的伴生类。\n",
    "\n",
    "伴生对象和伴生类信息可以共享，它们的属性和方法对彼此都是透明的。\n",
    "\n",
    "实际上在编译的时候，会把它们编译成一个Java类，伴生对象定义了这个Java类的静态属性和静态方法。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:23:59.850080Z",
     "start_time": "2019-08-25T10:23:59.610Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined object Hello\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Hello.name: String = China\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello World\n",
      "hello China\n"
     ]
    }
   ],
   "source": [
    "//单例对象\n",
    "object Hello{\n",
    "    var name = \"World\"\n",
    "    def main() = {\n",
    "        println(\"hello \" + name)\n",
    "    }\n",
    "}\n",
    "Hello.main()\n",
    "Hello.name = \"China\"\n",
    "Hello.main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 173,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:06.071481Z",
     "start_time": "2019-08-25T10:24:05.840Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined class Person\n",
       "defined object Person\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The id of LiLei is 1 \n",
      "The id of HanMeiMei is 2 \n"
     ]
    }
   ],
   "source": [
    "//伴生对象和伴生类\n",
    "class Person{\n",
    "    private var Id = Person.newPersonId()\n",
    "    private var name = \"\"\n",
    "    def this(name:String){\n",
    "        this()\n",
    "        this.name = name\n",
    "    }\n",
    "    def info(){\n",
    "        printf(\"The id of %s is %d \\n\",name,Id)\n",
    "    }\n",
    "}\n",
    "\n",
    "object Person{\n",
    "    private var lastId:Int = 0\n",
    "    private def newPersonId():Int = {\n",
    "        lastId += 1\n",
    "        lastId\n",
    "    }\n",
    "    def main(){\n",
    "        val person1 = new Person(\"LiLei\")\n",
    "        val person2 = new Person(\"HanMeiMei\")\n",
    "        person1.info()\n",
    "        person2.info()\n",
    "    }\n",
    "}\n",
    "\n",
    "Person.main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十四，继承和特征"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Scala可以通过extends关键字指定从某个超类(父类)进行继承。\n",
    "\n",
    "只有子类的主构造器可以调用超类的主构造器。\n",
    "\n",
    "子类可以使用super引用超类的某个属性和方法。\n",
    "\n",
    "子类如果要重写超类的某个属性和方法，需要使用override关键字。\n",
    "\n",
    "除非超类的该属性和该方法为抽象方法，只有声明没有定义。\n",
    "\n",
    "如果某个类定义时被abstract声明为抽象类时，它可以被继承但是不能直接被实例化。\n",
    "\n",
    "和Python语言不同，Scala每个类只能继承一个超类。\n",
    "\n",
    "为了实现多继承的功能，在指定一个超类的同时可以指定若干个trait特征进行继承。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 174,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:09.317984Z",
     "start_time": "2019-08-25T10:24:09.214Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined class Animal\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "//抽象类 \n",
    "abstract class Animal(n:String){\n",
    "    val name = n\n",
    "    val age:Int\n",
    "    var home = \"Earth\" \n",
    "    \n",
    "    def eat(food:String) //abstract method\n",
    "    \n",
    "    def sleep(){\n",
    "        println(\"Zzz...Zzz...Zzz...\")\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 175,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:11.733917Z",
     "start_time": "2019-08-25T10:24:11.519Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined class MyCat\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "//继承自上述抽象类\n",
    "class MyCat(n:String,a:Int) extends Animal(n){\n",
    "    \n",
    "    override val age = a\n",
    "    \n",
    "    override def eat(food:String){\n",
    "        printf(\"%s is eating %s...\\n\",name,food)\n",
    "    }\n",
    "    \n",
    "    override def sleep(){\n",
    "        printf(\"%s is sleeping ...\\n\",name)\n",
    "        super.sleep()\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 176,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:14.471953Z",
     "start_time": "2019-08-25T10:24:13.803Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Kitty\n",
      "Earth\n",
      "Kitty is eating fish...\n",
      "Kitty is sleeping ...\n",
      "Zzz...Zzz...Zzz...\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "kitty = MyCat@6d6fc588\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "MyCat@6d6fc588"
      ]
     },
     "execution_count": 176,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val kitty = new MyCat(\"Kitty\",10)\n",
    "\n",
    "println(kitty.name)\n",
    "println(kitty.home)\n",
    "kitty.eat(\"fish\")\n",
    "kitty.sleep()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 177,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:16.715356Z",
     "start_time": "2019-08-25T10:24:16.602Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined trait Flyable\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "//特征\n",
    "trait Flyable{\n",
    "    val fly_height:Int\n",
    "    def fly(){println(\"is flying...\")   \n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 178,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:19.376618Z",
     "start_time": "2019-08-25T10:24:18.667Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Poly\n",
      "Zzz...Zzz...Zzz...\n",
      "Poly is eating bug...\n",
      "Poly is flying...\n",
      "3\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined class Parrot\n",
       "poly = Parrot@6b99ee23\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Parrot@6b99ee23"
      ]
     },
     "execution_count": 178,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//同时继承超类和特征,如果有多个特征,用多个with连接\n",
    "class Parrot(n:String,a:Int,h:Int) extends Animal(n) \n",
    "with Flyable{\n",
    "    override val age = a\n",
    "    override val fly_height = h\n",
    "    override def eat(food:String){\n",
    "        printf(\"%s is eating %s...\\n\",name,food)\n",
    "    }\n",
    "    override def fly(){\n",
    "        print(name+\" \")\n",
    "        super.fly()\n",
    "    }\n",
    "}\n",
    "\n",
    "val poly = new Parrot(\"Poly\",3,3)\n",
    "\n",
    "println(poly.name)\n",
    "poly.sleep()\n",
    "poly.eat(\"bug\")\n",
    "poly.fly()\n",
    "println(poly.fly_height)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十五，apply,unapply和update方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当把对一个对象当做函数使用时，会自动调用它的apply方法。\n",
    "\n",
    "实践中我们一般用apply方法来构造对象，而无需用new声明一个对象，从而相当于一个语法糖。\n",
    "\n",
    "unapply方法是apply方法的逆方法，我们一般用它来从对象中反推得到其构造参数。\n",
    "\n",
    "unapply方法通常在模式匹配中会自动被使用。\n",
    "\n",
    "case类内部实现了apply方法和unapply方法。\n",
    "\n",
    "当把一个对象当做容器取其某个元素赋值时，会自动调用它的update方法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，内部范例**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 179,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:24.157407Z",
     "start_time": "2019-08-25T10:24:23.596Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "arr = Array(0, 0, 0)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(0, 0, 0)"
      ]
     },
     "execution_count": 179,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//new一个对象\n",
    "val arr = new Array[Int](3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 180,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:24.927035Z",
     "start_time": "2019-08-25T10:24:24.093Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "arr = Array(1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(1, 2, 3)"
      ]
     },
     "execution_count": 180,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//隐式调用apply方法构造一个对象,工厂方法\n",
    "val arr = Array(1,2,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 181,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:25.724067Z",
     "start_time": "2019-08-25T10:24:24.655Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "arr = Array(1, 2, 3)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Array(1, 2, 3)"
      ]
     },
     "execution_count": 181,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//显式调用apply方法构造一个对象\n",
    "val arr = Array.apply(1,2,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 182,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:25.907044Z",
     "start_time": "2019-08-25T10:24:25.112Z"
    }
   },
   "outputs": [],
   "source": [
    "//隐式调用update方法\n",
    "arr(0) = 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:26.672247Z",
     "start_time": "2019-08-25T10:24:25.523Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(2, 2, 3)"
      ]
     },
     "execution_count": 183,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//显式调用update方法\n",
    "arr.update(2,3)\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:27.652984Z",
     "start_time": "2019-08-25T10:24:27.017Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Some((LiLei,18))\n",
      "(name:,LiLei, age:,18)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined class Person\n",
       "person = Person(LiLei,18)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Person(LiLei,18)"
      ]
     },
     "execution_count": 184,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//示范case类的apply方法和unapply方法\n",
    "case class Person(name:String,age:Int)\n",
    "//val person = Person.apply(\"LiLei\",18)\n",
    "val person = Person(\"LiLei\",18)\n",
    "println(Person.unapply(person))\n",
    "person match{\n",
    "    case Person(name,age) => println(\"name:\",name,\" age:\",age)\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，apply演示**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:14:08.180572Z",
     "start_time": "2019-08-25T10:14:07.035Z"
    }
   },
   "outputs": [],
   "source": [
    "class Money(val value:Double,val country:String){\n",
    "    def apply(){\n",
    "        println(country+\" \"+value)\n",
    "    }\n",
    "}\n",
    "\n",
    "object Money {\n",
    "    def apply(value:Double,country:String):Money = {\n",
    "        new Money(value,country)\n",
    "    }\n",
    "}\n",
    "\n",
    "\n",
    "val money1 = new Money(12.0,\"RMB\")\n",
    "println(money1.country)\n",
    "\n",
    "\n",
    "val money2 = Money(80.0,\"USD\") \n",
    "println(money2.value)\n",
    "\n",
    "money1()\n",
    "money2()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3，unapply演示**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 185,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:38.684740Z",
     "start_time": "2019-08-25T10:24:38.107Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RMB 10.1\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined class Money\n",
       "defined object Money\n",
       "money = Money@60fef172\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Money@60fef172"
      ]
     },
     "execution_count": 185,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Money(val value:Double,val country:String){\n",
    "    def apply(){\n",
    "        println(country+\" \"+value)\n",
    "    }\n",
    "}\n",
    "\n",
    "object Money {\n",
    "    def apply(value:Double,country:String):Money = {\n",
    "        new Money(value,country)\n",
    "    }\n",
    "    def unapply(money:Money):Option[(Double,String)] = {\n",
    "        if(money == null) {\n",
    "            None\n",
    "        }\n",
    "        else {\n",
    "            Some(money.value,money.country)\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "//测试unapply类，在模式匹配时被调用，case类内部已经实现\n",
    "val money =  Money(10.1, \"RMB\") \n",
    "money match { \n",
    "   case Money(num, \"RMB\") => println(\"RMB \" + num) \n",
    "   case _ => println(\"Not RMB!\")\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十六，wordcount范例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 186,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-25T10:24:42.299701Z",
     "start_time": "2019-08-25T10:24:41.702Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "wordcount/file2\n",
      "wordcount/file1\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined object WordCount\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Map(XiCheng -> 1, world -> 1, China -> 2, TianAnMen -> 1, BeiJing -> 2, hello -> 5)\n",
      "XiCheng: 1\n",
      "world: 1\n",
      "China: 2\n",
      "TianAnMen: 1\n",
      "BeiJing: 2\n",
      "hello: 5\n"
     ]
    }
   ],
   "source": [
    "import java.io.File\n",
    "import scala.io.Source\n",
    "object WordCount {\n",
    "  def main(args: Array[String]): Unit = {\n",
    "    val dirfile=new File(\"wordcount\")\n",
    "    val files=dirfile.listFiles\n",
    "    for(file <- files) println(file)\n",
    "    val listFiles=files.toList\n",
    "    val wordsMap=scala.collection.mutable.Map[String,Int]()\n",
    "    listFiles.foreach( file =>Source.fromFile(file).\n",
    "                      getLines().foreach(line=>line.split(\" \").\n",
    "                  foreach(\n",
    "                      word=>{\n",
    "                        if (wordsMap.contains(word)) {\n",
    "                          wordsMap(word)+=1\n",
    "                        }else {\n",
    "                          wordsMap+=(word->1)\n",
    "                        }\n",
    "                      }\n",
    "                  )\n",
    "            )\n",
    "\n",
    "    )\n",
    "    println(wordsMap)\n",
    "    for((key,value)<-wordsMap) println(key+\": \"+value)\n",
    "  }\n",
    "}\n",
    "\n",
    "WordCount.main(Array(\"test\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十七，scala语言的设计哲学\n",
    "\n",
    "1，一切皆对象\n",
    "\n",
    "从整数，字符串，函数，类到各种数据结构，Scala中一切皆为对象，Any是它们的超类。\n",
    "\n",
    "2，一切皆表达式\n",
    "\n",
    "Scala中书写的每条语句都可以看成是一条表达式。\n",
    "\n",
    "表达式的基本格式是 name:type = {...} \n",
    "\n",
    "name是对象标识符，type是它的类型，{}括起来的作用域部分都是它的值。\n",
    "\n",
    "从变量的定义，函数的定义，判断语句，循环语句到类的定义，\n",
    "\n",
    "都可以看成是这个格式省去某些部分的特例或语法糖等价书写形式。\n",
    "\n",
    "\n",
    "3，简洁而富有表现力\n",
    "\n",
    "同样的功能，scala的代码量可能不到Java的五分之一。\n",
    "\n",
    "并且scala的许多特性设计非常有表现力。\n",
    "\n",
    "简洁范例：强大的自动类型推断，隐含类型转换，匿名函数，case类，字符串插值器。\n",
    "\n",
    "表现力范例：集合的&和|运算,函数定义的=>符号,\n",
    "\n",
    "for循环<-的符号，Map的 ->符号，\n",
    "\n",
    "以及生成range的 1 to 100等表达。\n",
    "\n",
    "4，函数式编程\n",
    "\n",
    "函数的特点是操作无副作用，唯一的作用的生成函数值。\n",
    "\n",
    "把一个函数作用到一些参数上，不会对输入参数造成改变。\n",
    "\n",
    "为了逼近这个目标，scala设计的默认数据结构绝大部分是不可变的。\n",
    "\n",
    "并且在一个良好风格的scala程序中，只需要使用val不可变变量而无需使用var可变变量。\n",
    "\n",
    "显式的for或者while循环是不可取的，让我们用更多的高阶函数吧。\n",
    "\n",
    "5，多范式编程\n",
    "\n",
    "尽管函数式编程是Scala的推荐编程范式，但Scala同时混合了强大的命令式编程的功能。\n",
    "\n",
    "你可以使用强大的for循环，for推导式，使用可变的变量和数据类型实现命令式编程。\n",
    "\n",
    "你还可以使用强大的模式匹配，基于模式匹配完成复杂的变换操作，实现模式化编程。\n",
    "\n",
    "最后，正如同它的名字的蕴意，Scala是一门可以伸缩的语言。\n",
    "\n",
    "通过编写扩展类和对象，或继承各种Trait生成新数据结构，\n",
    "\n",
    "Scala可以很容易地成为某个领域的\"专业语言\"。\n",
    "\n",
    "新增加的那些特性就好像是scala语法本身的一部分。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Appendix：参考资料\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1，林子雨《Spark编程基础》\n",
    "\n",
    "https://study.163.com/course/courseMain.htm?courseId=1005031005\n",
    "\n",
    "http://dblab.xmu.edu.cn/blog/spark/\n",
    "\n",
    "2，菜鸟教程《Scala教程》\n",
    "\n",
    "https://www.runoob.com/scala/scala-tutorial.html\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Spark - Scala",
   "language": "scala",
   "name": "spark_scala"
  },
  "language_info": {
   "codemirror_mode": "text/x-scala",
   "file_extension": ".scala",
   "mimetype": "text/x-scala",
   "name": "scala",
   "pygments_lexer": "scala",
   "version": "2.11.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
